<template>
  <div class="todoapp">
    <!-- 使用组件 -->
    <todo-header :list="list" @addTask="addTaskHandler"></todo-header>
    <todo-main @delTask="delTaskHandler" :list="showList"></todo-main>
    <todo-footer
      @changeTask="changeTaskHandler"
      @clearDone="clearDoneHandler"
      :list="showList"
    ></todo-footer>
  </div>
</template>

<script>
// 父传子的流程:
// 子组件中定义 props 接收数据, 并使用
// 父组件中绑定属性传递数据

// 子传父的流程:
// 父组件中给子组件绑定一个自定义事件
// 子组件在恰当的时机触发事件并传递数据

// 目标1: 渲染列表
// 1.1 在 App.vue 中声明数据 list, 并传递给子组件 TodoMain.vue
// 1.2 使用 v-for 循环渲染 li, 动态绑定数据
// 1.3 使用 v-model 绑定勾选状态
// 1.4 动态 class 根据 isDone 来绑定类名

// 目标2: 添加数据
// 2.1 在 TodoHeader.vue 中双向绑定文本框, 同时绑定键盘按下事件(.enter 修饰符)
// 2.2 当用户输入内容后按下回车时, 将任务名传递给父组件
// 2.3 父组件封装成对象后添加到数组中
// 2.4 在 TodoHeader.vue 中如果用户输入回车添加数据后, 清空文本框
// 2.5 进行非空校验

// 目标3: 删除数据
// 3.1 在 TodoMain.vue 中给删除按钮绑定点击事件, 并传入 id
// 3.2 利用子传父技术将 id 传递给父组件 App.vue
// 3.3 在父组件中通过 id 找到对应数据的索引, 删除数据
// 3.4 数据全部删完后再添加需要处理 id 的 bug

// 目标4: 剩余数量统计
// 4.1 在 App.vue 中将 list 传入 TodoFooter.vue
// 4.2 在剩余数量处使用插值表达式渲染 list.length

// 目标5: 数据切换
// 需求1: 点谁谁亮
// 5.1 定义状态 isAll 取值范围是 all / yes / no
// 5.2 给三个 a 标签绑定动态 class, 分别判断是自己的状态时才应用 selected 类名
// 5.3 给三个 a 标签绑定点击事件, 点击时切换 isSel 为自己的状态
// 需求2: 数据切换
// 5.4 在 TodoFooter 中给 ul 绑定事件(事件委托)
// 5.5 isSel 变化时将数据传递给 App.vue
// 5.6 将子组件传递过来的数据存储在 data 中
// 5.7 定义计算属性, 根据 data 中的 isSel 来决定返回什么数据(filter 筛选数据)
// 5.8 修改传递给 TodoMain 和 TodoFooter 的 list 为 showList

// 目标6: 清除已完成
// 6.1 TodoFooter.vue 中给清除已完成标签绑定点击事件
// 6.2 子传父技术, 触发父组件的事件, 无需传递数据
// 6.3 App.vue 中直接操作原数组 list, 筛选出未完成的任务数组直接覆盖给 list

// 目标7: 数据缓存
// 7.1 在 App.vue 中使用 watch 深度侦听 list
// 7.2 当 list 变化时存入 localStorage (JSON.stringify)
// 7.3 页面加载时, 默认从 localStorage 中取出数据, 注意默认值的处理

// 目标8: 全选功能
// 需求1: 全选影响小选
// 8.1 将 list 从 App.vue 中传给 TodoHeader.vue
// 8.2 定义计算属性 isAll, 在 set 方法中同步 list 中所有的数据 isDone 属性
// 需求2: 小选影响全选
// 8.3 在 get 方法中使用 every 同步所有的勾选状态
// 8.4 需要处理无数据的情况

// 引入组件
import "./styles/base.css";
import "./styles/index.css";

import TodoHeader from "./components/TodoHeader.vue";
import TodoMain from "./components/TodoMain.vue";
import TodoFooter from "./components/TodoFooter.vue";
export default {
  // 注册组件
  components: {
    TodoHeader,
    TodoMain,
    TodoFooter,
  },
  data() {
    return {
      list: JSON.parse(localStorage.getItem("list") || "[]"),
      isSel: "all",
    };
  },
  methods: {
    addTaskHandler(taskName) {
      // 当数据删除完毕后需要处理 id
      let id =
        this.list.length > 0 ? this.list[this.list.length - 1].id + 1 : 100;
      this.list.push({
        id,
        name: taskName,
        isDone: false,
      });
    },
    delTaskHandler(id) {
      // console.log(id)
      // 根据 id 找索引并删除
      let index = this.list.findIndex((item) => item.id === id);
      this.list.splice(index, 1);
    },
    changeTaskHandler(isSel) {
      this.isSel = isSel;
    },
    clearDoneHandler() {
      // 删除已完成
      // 由于 showList 依赖原数组 list, 所以直接操作原数组 list 即可, 数据变化 showList 会自动更新
      this.list = this.list.filter((item) => !item.isDone);
    },
  },
  computed: {
    showList() {
      // 根据 isSel 的值来决定筛选什么数据返回
      if (this.isSel === "no") {
        return this.list.filter((item) => !item.isDone);
      } else if (this.isSel === "yes") {
        return this.list.filter((item) => item.isDone);
      } else {
        return this.list;
      }
    },
  },
  watch: {
    list: {
      deep: true,
      handler() {
        // 将 this.list 数据存入本地
        localStorage.setItem("list", JSON.stringify(this.list));
      },
    },
  },
};
</script>

<style lang="scss" scoped>
</style>